﻿//using Microsoft.AspNetCore.Http;

using System.Reflection;
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Text.Json;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using System.Text.Encodings.Web;
using Infrastructure.Converter;
using ZR.Infrastructure.Converter;
using Newtonsoft.Json.Linq;
using System.ComponentModel;
using Infrastructure.Extensions;

namespace Infrastructure.Filters
{
    public static class ResponseExtensions
    {
        /// <summary>
        /// 提取异常数据（待填充）
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        internal static (int code, string message) GetException(this ExceptionContext context)
        {
            var metas = context.HttpContext.RequestServices.GetService<IDictionary<ResponseStateEnum, ResponseStateAttribute>>();
            //业务异常
            if (context.Exception is CustomException)
            {
                var ex = (context.Exception as CustomException);
                var msg = ex.Msg;
                if (string.IsNullOrWhiteSpace(msg))
                {
                    msg = ex.Code.ToDesc();
                }
                return ((int)ex.Code, msg);
            }
            //其他异常
            var serverErrorInfo = metas[ResponseStateEnum.ServerError];
            return (serverErrorInfo.Code, serverErrorInfo.Message);
        }


        internal static (int code, string message) GetException(this HttpContext context, ResponseStateEnum status)
        {
            var metas = context.RequestServices.GetService<IDictionary<ResponseStateEnum, ResponseStateAttribute>>();
            return (metas[status].Code, metas[status].Message);
        }

        internal static int GetResponseStateCode(this ResponseStateEnum rspState)
        {
            var field = rspState.GetType().GetField(rspState.ToString());
            return field?.GetCustomAttribute<ResponseStateAttribute>()?.Code??0;
        }

        internal static Object GetContext(this ActionExecutedContext context)
        {
            var logger = HttpContextGlobal.Current.RequestServices.GetService(typeof(ILogger<ApiResultProvider>)) as ILogger;
            if (context.Result is ContentResult contentResult)
            {
                return contentResult.Content;
            }
            else if (context.Result is ObjectResult objectResult)
            {
                return objectResult.Value;
            }
            else if (context.Result is EmptyResult)
                return null;
            else return null;
        }

        /// <summary>
        /// 序列化对象
        /// </summary>
        //
        public static string ToJson(this object obj, JsonSerializerOptions jsonSerializerOptions = default)
        {
            return JsonSerializer.Serialize(obj, jsonSerializerOptions ?? GetDefaultJsonSerializerOptions());
        }

        /// <summary>
        /// 获取默认 JSON 序列化选项
        /// </summary>
        /// <returns></returns>
        public static JsonSerializerOptions GetDefaultJsonSerializerOptions(bool isCaseInsensitive = false)
        {
            var jsonSettings = new System.Text.Json.JsonSerializerOptions();
            jsonSettings.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
            jsonSettings.Converters.Add(new JsonConverterUtil.DateTimeConverter());
            jsonSettings.Converters.Add(new JsonConverterUtil.DateTimeNullConverter());
            jsonSettings.Converters.Add(new Infrastructure.Converter.StringConverter());
            jsonSettings.Converters.Add(new LongToStringConverter());

            return jsonSettings;
        }

        /// <summary>
        /// 获取方法真实返回类型
        /// </summary>
        /// <param name="method"></param>
        /// <returns></returns>
        internal static Type GetMethodRealReturnType(this MethodInfo method)
        {
            // 判断是否是异步方法
            var isAsyncMethod = method.IsAsync();

            // 获取类型返回值并处理 Task 和 Task<T> 类型返回值
            var returnType = method.ReturnType;
            return isAsyncMethod ? (returnType.GenericTypeArguments.FirstOrDefault() ?? typeof(void)) : returnType;
        }

        /// <summary>
        /// 判断方法是否是异步
        /// </summary>
        /// <param name="method">方法</param>
        /// <returns></returns>
        internal static bool IsAsync(this MethodInfo method)
        {
            return method.ReturnType.IsAsync();
        }

        /// <summary>
        /// 判断类型是否是异步类型
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        internal static bool IsAsync(this Type type)
        {
            return type.ToString().StartsWith(typeof(Task).FullName);
        }

        /// <summary>
        /// 判断类型是否实现某个泛型
        /// </summary>
        /// <param name="type">类型</param>
        /// <param name="generic">泛型类型</param>
        /// <returns>bool</returns>
        internal static bool HasImplementedRawGeneric(this Type type, Type generic)
        {
            // 检查接口类型
            var isTheRawGenericType = type.GetInterfaces().Any(IsTheRawGenericType);
            if (isTheRawGenericType) return true;

            // 检查类型
            while (type != null && type != typeof(object))
            {
                isTheRawGenericType = IsTheRawGenericType(type);
                if (isTheRawGenericType) return true;
                type = type.BaseType;
            }

            return false;

            // 判断逻辑
            bool IsTheRawGenericType(Type type) => generic == (type.IsGenericType ? type.GetGenericTypeDefinition() : type);
        }

        /// <summary>
        /// 输出验证信息
        /// </summary>
        /// <param name="errors"></param>
        /// <returns></returns>
        internal static (Dictionary<string, IEnumerable<string>> validationResults, string validateFaildMessage, ModelStateDictionary modelState) OutputValidationInfo(this object errors)
        {
            ModelStateDictionary _modelState = null;
            Dictionary<string, IEnumerable<string>> validationResults = null;

            if (errors is ModelStateDictionary modelState)
            {
                _modelState = modelState;
                validationResults = modelState.ToDictionary(u => u.Key, u => modelState[u.Key].Errors.Select(c => c.ErrorMessage));
            }
            else if (errors is ValidationProblemDetails validation)
            {
                validationResults = validation.Errors.ToDictionary(u => u.Key, u => u.Value.AsEnumerable());
            }
            else validationResults = new Dictionary<string, IEnumerable<string>>
            {
                { "", new[] { errors?.ToString() } }
            };
            var validateFaildMessage = JsonSerializer.Serialize(validationResults);

            return (validationResults, validateFaildMessage, _modelState);
        }
    }
}
